import sys

import fuzzywuzzy.fuzz as fz
# import numpy as np
# from PyQt5.Qt import QCompleter
# from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import QStandardItemModel
from PyQt5.QtCore import QModelIndex, pyqtProperty, QPropertyAnimation, QTimer
from PyQt5.QtGui import QStandardItem, QColor, QBrush, QFont, QPalette
from PyQt5.QtWidgets import QApplication, QHeaderView, QStatusBar, QLabel, QPushButton, QStyle, QShortcut, QMessageBox
from PyQt5.QtWidgets import QMainWindow
# from numpy.core.defchararray import isnumeric

from utility import banks_load_for
# from View import interface
from ui.JarvisWin import Ui_MainWindow
from Jarvis import *
import re

agents = banks_load_for('all_agent_count')  # pd.frame
sentTo = banks_load_for('sentTo')
alias = banks_load_for('alias_agent')  # dic
workers = banks_load_for('worker')
approve = banks_load_for(kApprove)
owners = banks_load_for(kOwner)
contents = banks_load_for(kCon)


def get_field_from(s):
    # extract the number
    s = re.sub(r' +', ' ', s)
    s = re.sub(r'\n+', '\n', s)

    res = re.findall('[\s]+\d{1,3}[\s]', s)
    if res:
        number = re.findall('\d+', res[0])[0]
        s = s.replace(res[0], res[0][-1])
    else:
        number = ''
    lines = s.split('\n')
    lines = list(filter(lambda s: s.strip() != '', lines))
    n = len(lines)
    if n < 1: return None
    if s[-1] == '\n':
        lines.append('')
        n += 1
    fields = {'agent': '',
              'sentTo': '',
              'approve': '',
              'worker': '',
              'owner': '',
              'content': '',
              kNum: number,
              'now': '',
              'next': '用章单位',
              'newLine': False}
    if n < 1:
        return fields
    if ' ' in lines[0]:
        ss = lines[0].split(' ')
        n2 = len(ss)
        fields[kAgent] = ss[0]
        fields['next'] = '发往单位'
        if n2 > 1:
            fields[kSent] = ss[1]
            fields['now'] = '发往单位'
            fields['next'] = '批准单位'
        if n2 > 2:
            fields[kApprove] = ss[2]
            fields['now'] = '批准单位'
            fields['next'] = '内容'
            fields['newLine'] = True
    else:
        fields['now'] = '用章单位'
        fields['agent'] = lines[0]
        fields['next'] = '发往单位'

    # here finish agent []
    if n < 2: return fields
    fields[kCon] = lines[1]
    fields['now'] = '内容'
    fields['next'] = '经办人'
    fields['newLine'] = True
    if n < 3: return fields
    fields['newLine'] = False
    if ' ' in lines[2]:
        ss = lines[2].split(' ')
        fields[kWorker] = ss[0]
        fields['now'] = '经办人'
        fields['next'] = '申请人'
        if len(ss) > 1:
            fields[kOwner] = ss[1]
            fields['now'] = '申请人'
            fields['next'] = '用章数量'
            fields['newLine'] = True
    else:
        fields[kWorker] = lines[2]
        fields['now'] = '经办人'
        fields['next'] = '申请人'

    if fields['next'] == '用章数量' and fields[kNum] != '':
        fields['next'] = 'done'
    return fields


def sort_result_by_name(word: str, results: list) -> list:
    res2 = []
    for r in results:
        if r.startswith(word):
            res2.append(r)
    for r in res2:
        results.remove(r)
    res2.extend(results)
    return res2


def search_in(word: str, field: str, ratio_threshold='auto', result_limit=10):
    result = []
    banks_map = {kAgent: agents,
                 kSent: sentTo,
                 kApprove: approve,
                 kWorker: workers,
                 kCon: contents,
                 kOwner: owners}
    if field not in banks_map:
        return [word]
    bank = banks_map[field]
    if ratio_threshold == 'auto':
        if len(word) <= 3 or len(word) >= 8:
            ratio_threshold = 90
        else:
            ratio_threshold = 30
    for agent in bank.index:
        if type(agent) is not str: continue
        d = fz.partial_ratio(agent, word)
        if d > ratio_threshold:
            result.append(agent)
            if len(result) > result_limit: break
    return sort_result_by_name(word, result)


class MainWindow(QMainWindow, Ui_MainWindow):

    def __init__(self):

        super(MainWindow, self).__init__(None)
        self.waiting_on_timer = False
        self.ks_col = {}
        self.col_ks = [kAgent, kSent, kApprove, kCon, kWorker, kOwner]
        self.block_flags = {}
        for i, k in enumerate(self.col_ks):
            self.ks_col[k] = i
            self.block_flags[k] = False

        self.model = QStandardItemModel()
        self.setupUi(self)
        # self.statusbar.show
        self.statusBar().showMessage('嗨，别来无恙')

        self.setWindowTitle('Jarvis')
        self.add_table_header()
        self.textEdit_2.cursorPositionChanged.connect(self.event_cur_changed)
        # self.selected_fields = [''] * 6
        self.selected_fields_ = {'agent': '',
                                 'sentTo': '',
                                 'approve': '',
                                 'worker': '',
                                 'owner': '',
                                 'content': '',
                                 kNum: ''}
        self.last_fields_ = {'agent': '',
                             'sentTo': '',
                             'approve': '',
                             'worker': '',
                             'owner': '',
                             'content': '',
                             kNum: ''}
        self.last_text = ''

        self.anim = QPropertyAnimation(self, b"status_color")
        # self.but_anim = QPropertyAnimation(self, b"button_color")
        # self.but_anim.setDuration(1000)
        # self.but_anim.setStartValue(QColor(221, 239, 217))
        # self.but_anim.setKeyValueAt(0.5, QColor(205, 255, 158))
        # self.but_anim.setEndValue(QColor(90,250,176)) #190,250,176 -> hsv(221,239,217)
        # self.but_anim.setLoopCount(1)
        self.doAnim()

        # self.sc_auto_cmplt.activated.connect(self.action_auto_complete)
        # self.action_auto_complete.setShortcut('Ctrl+N')
        # self.textEdit_2.short

        self.msgSc = QShortcut('Ctrl+M', self)
        self.msgSc.activated.connect(self.event_action_auto_complete)

        self.msgSc = QShortcut('Ctrl+L', self)
        self.msgSc.activated.connect(self.event_action_auto_complete2)

        msgSc3 = QShortcut('Ctrl+Space', self)
        msgSc3.activated.connect(lambda:print('Space'))



    def doAnim(self):
        self.anim.setDuration(30000)
        self.anim.setStartValue(QColor(221, 239, 217))  # 粉色
        self.anim.setKeyValueAt(0.25, QColor(190, 250, 176))  # 红色
        self.anim.setKeyValueAt(0.5, QColor(205, 255, 158))  # 红色
        self.anim.setKeyValueAt(0.75, QColor(214, 106, 91))
        self.anim.setEndValue(QColor(221, 239, 217))  # 米黄

        self.anim.setLoopCount(-1)
        self.anim.start()

    def play_done(self):
        self.waiting_on_timer = False
        self.doAnim()

    def show_warning(self, msg: str):
        self.anim.stop()
        self.anim.setDuration(8000)
        self.anim.setStartValue(QColor(20, 191, 204))  # 粉色
        self.anim.setKeyValueAt(0.5, QColor(214, 106, 91))
        self.anim.setEndValue(QColor(221, 239, 217))  # 米黄
        self.anim.setLoopCount(1)
        self.anim.start()
        self.show_msg(msg)
        # print('\a')
        if not self.waiting_on_timer:
            QTimer.singleShot(10000, self.play_done)
            self.waiting_on_timer = True

    def show_msg(self, msg: str):
        if not self.waiting_on_timer:
            self.statusbar.showMessage(msg, -1)
        else:
            s = self.statusbar.currentMessage()
            s += ' // ' + msg
            self.statusbar.showMessage(s, -1)

    def add_table_header(self):
        self.tableView.setModel(self.model)
        for i, header in enumerate('申请单位 发往单位 批准单位 内容 经办人 申请人'.split(' ')):
            m = QStandardItem(header)
            # m.setForeground(QColor(255,255,255))
            m.setBackground(QBrush(QColor(3, 147, 176, 80)))
            m.font().setBold(True)

            self.model.setHorizontalHeaderItem(i, m)
            # self.model.horizontalHeaderItem(i).setBackground(QColor(89, 168, 105))

        self.model.setRowCount(20)
        for i in range(20):
            for j in range(len(self.ks_col)):
                self.model.setItem(i, j, QStandardItem(''))
        for i in range(len(self.ks_col)):
            # self.model.item(0, i).setBackground(QColor(3, 147, 176, 80))
            f = self.model.item(0, i).font()
            f.setBold(True)
            f.setPointSize(f.pointSize() + 2)
            self.model.item(0, i).setFont(f)
        self.tableView.horizontalHeader().setSectionResizeMode(self.ks_col[kCon], QHeaderView.Stretch)

    def event_cur_changed(self):
        text = self.textEdit_2.toPlainText()
        if self.last_text == text:  # no change
            return
        if text == '':
            self.last_text = ''
            return
        n = self.textEdit_2.textCursor().anchor() - 1
        c = text[n]
        if n > 0 and len(text) > len(self.last_text) and c == '\n' and text[n - 1] == '\n':
            s = text.replace('\n', '')
            if s != '' and self.selected_fields_[kCon] == '':
                # try assistant
                ok, msg = append_last_number(s)
                if not ok:
                    self.show_warning(msg)
                else:
                    self.show_msg('上一行[用章数量]:' + msg)
                    self.textEdit_2.clear()
            else:
                self.event_button_clicked()
            self.last_text = text
            return

        self.last_text = text
        done = self.parse_text(text)
        if done and c == '\n':
            self.event_button_clicked()

    def event_table_clicked(self, m: QModelIndex):
        # print(m)
        i = m.row()
        if i == 0: return
        j = m.column()
        s = self.model.item(i, j).text()
        # print('clicked:', s)
        if s != '':
            self.selected_fields_[self.col_ks[j]] = s
            self.show_out()
            self.block_flags[self.col_ks[j]] = True  # block this field
            self.model.item(0, j).setBackground(QColor(3, 147, 176, 80))

    def event_table_entered(self, m: QModelIndex):
        i = m.row()
        if i != 0: return
        j = m.column()

        self.block_flags[self.col_ks[j]] = True  # block this field
        self.model.item(0, j).setBackground(QColor(3, 147, 176, 80))

    def event_on_action(self, *qAction):
        pass

    def event_action_auto_complete(self):
        print('action')
    def event_action_auto_complete2(self):
        print('action2')


    def guess_field(self):
        if self.selected_fields_[kApprove] == '':
            con = self.selected_fields_[kCon]
            maybe = '科发院'
            book = {'退休': '离退休办'}
            for b in book:
                if b in con:
                    maybe = book[b]
                    break
            if '证书' in con and ('硕' in con or '博' in con):
                maybe = '研究生院'
            self.selected_fields_[kApprove] = maybe
            self.show_warning('[批准单位]缺省, 填充为: ' + maybe)

    def event_button_clicked(self):
        # self.but_anim.start()
        if self.selected_fields_[kAgent] == '':
            self.show_warning('[用章单位]为空')
        if self.selected_fields_[kCon] != '':
            self.guess_field()
        for i, k in enumerate(self.ks_col):
            self.selected_fields_[k] = self.selected_fields_[k].replace('_', ' ')
            if self.selected_fields_[k] == '-':
                self.selected_fields_[k] = ''
            if not self.block_flags[k]: continue
            self.selected_fields_[k] = self.model.item(0, i).text()
            self.block_flags[k] = False
            self.model.item(0, i).setBackground(QColor(255, 255, 255))
        ok, msg, num = add_a_record(self.selected_fields_)

        if not ok:
            self.show_warning(msg)
            return
        self.textEdit_2.clear()
        change = False
        for i, k in enumerate(self.ks_col):
            if self.selected_fields_[k] != '':
                self.selected_fields_[k] = ''
                change = True
            self.last_fields_[k] = ''
        if not change:
            self.show_warning('空表单')
        self.label.setText(num)

    def parse_text(self, s: str):
        s = s.replace('\t', ' ')
        field = get_field_from(s)
        if field is None: return
        s = ''
        if field['now'] != '':
            s = '当前项目: ' + field['now'] + ', '

        if field['newLine']:
            s += ' 回车, '
        if field['next'] == 'done':
            s += '完成, 回车确认'
        else:
            s += '下一项目: ' + field['next']
        self.show_msg(s)
        update = False

        for k in self.ks_col:
            if self.block_flags[k]:
                continue  # skip this field
            col = self.ks_col[k]
            a = field[k]
            if a == '' and self.selected_fields_[k] == '':
                continue

            if a == '':
                self.selected_fields_[k] = ''
                update = True
                continue

            if k == kCon and '——' in a:
                a = a[:a.index('——')]
                s = field[kCon]
                s = s[s.index('——') + 2:]
                s1 = self.selected_fields_[kCon]
                if '——' in s1:
                    n = s1.index('——')
                    s1 = s1[:n]
                    s2 = s1[n + 2:]
                    if s2 != s:
                        self.selected_fields_[kCon] = s1 + '——' + s
                        update = True
                else:
                    self.selected_fields_[kCon] = s1 + '——' + s
                    update = True

            if a == self.last_fields_[k]: continue
            self.last_fields_[k] = a

            maybe = search_in(a, k)
            for i, b in enumerate(maybe):
                self.model.item(i + 1, col).setText(b)
            if len(maybe) == 0 and self.selected_fields_[k] != a:
                self.selected_fields_[k] = a
                update = True
            elif len(maybe) > 0 and self.selected_fields_[k] != maybe[0]:
                self.selected_fields_[k] = maybe[0]
                update = True
            # for content
            if k == kCon and '——' in field[kCon]:
                s = field[kCon]
                self.selected_fields_[kCon] += s[s.index('——'):]
                update = True
        k = kNum
        if self.selected_fields_[k] != field[k]:
            self.selected_fields_[k] = field[k]
            update = True
        if update:
            self.show_out()
            # self.selected_fields = field
        if field['next'] == 'done':
            return True
        return False

    def show_out(self):
        s = ''
        fs = self.selected_fields_
        s = fs[kAgent] + ' ' + fs[kSent] + ' '

        if fs[kNum] != '':
            s += '#' + fs[kNum] + ' '
        s += fs[kWorker] + ' '
        if fs[kOwner] != '':
            s += '（' + fs[kOwner] + ' '

        s += '\n:' + fs[kCon]
        # if len(self.selected_fields) > 0:
        #     s = self.selected_fields[0] + ' '

        self.textEdit.setText(s)
        for i, k in enumerate(self.col_ks):
            self.model.item(0, i).setText(self.selected_fields_[k])

    # def initUI(self):
    #     layout = QGridLayout()
    #     layout.setSpacing(10)
    #     self.loginLabel = QLabel("邮箱：")
    #     self.loginLabel.setAlignment(Qt.AlignRight)
    #     self.loginLabel.setStyleSheet("color:rgb(20,20,20,255);font-size:16px;font-weight:bold:text")
    #
    #     self.loginTxt = QLineEdit()
    #     self.loginTxt.setText("admin")
    #     self.loginTxt.setPlaceholderText("User Name")
    #     self.loginTxt.setClearButtonEnabled(True)
    #     self.loginTxt.textChanged.connect(self.on_loginTxt_textChanged)  # 绑定槽函数
    #     self.m_model = QStandardItemModel(0, 1, self)
    #     m_completer = QCompleter(self.m_model, self)
    #     self.loginTxt.setCompleter(m_completer)
    #     m_completer.activated[str].connect(self.onTxtChoosed)
    #
    #     self.pwdLabel = QLabel("密码：")
    #     self.pwdLabel.setAlignment(Qt.AlignRight)
    #     self.pwdTxt = QLineEdit()
    #     self.pwdTxt.setContextMenuPolicy(Qt.NoContextMenu)  # 禁止复制粘贴
    #     self.pwdTxt.setPlaceholderText("Password")
    #     self.pwdTxt.setText("admin")
    #     self.pwdTxt.setEchoMode(QLineEdit.Password)
    #     self.pwdTxt.setClearButtonEnabled(True)
    #     self.registeredBtn = QPushButton("注册")
    #     self.loginBtn = QPushButton("登陆")
    #
    #     self.headLabel = QLabel("用户登陆")
    #     self.headLabel.resize(300, 30)
    #     self.headLabel.setAlignment(Qt.AlignCenter)
    #     self.headLabel.setStyleSheet("color:rgb(10,10,10,255);font-size:25px;font-weight:bold;font-family:Roman times;")
    #
    #     self.headLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
    #     layout.addWidget(self.headLabel, 0, 0, 1, 2)
    #     policy = self.headLabel.sizePolicy()
    #     print(policy.verticalPolicy())
    #     policy.setVerticalPolicy(1)
    #     print(policy.verticalPolicy())
    #     # policy.setVerticalPolicy(1)
    #     layout.addWidget(self.loginLabel, 1, 0)
    #     layout.addWidget(self.loginTxt, 1, 1)
    #     layout.addWidget(self.pwdLabel, 2, 0)
    #     layout.addWidget(self.pwdTxt, 2, 1)
    #     layout.addWidget(self.registeredBtn, 3, 0)
    #     layout.addWidget(self.loginBtn, 3, 1)
    #
    #     frame = QFrame(self)
    #     frame.setLayout(layout)
    #     self.setCentralWidget(frame)
    #     self.resize(300, 150)
    #
    # def onTxtChoosed(self, txt):
    #     self.loginTxt.setText(txt)
    #
    # @pyqtSlot(str)
    # def on_loginTxt_textChanged(self, text):
    #     if '@' in self.loginTxt.text():
    #         return
    #
    #     emaillist = ["@163.com", "@qq.com", "@gmail.com", "@live.com", "@126.com", "@139.com"]
    #     self.m_model.removeRows(0, self.m_model.rowCount())
    #     for i in range(0, len(emaillist)):
    #         self.m_model.insertRow(0)
    #         self.m_model.setData(self.m_model.index(0, 0), text + emaillist[i])

    def _set_bar_color(self, col):
        r, g, b, _ = col.getRgb()
        self.statusbar.setStyleSheet(
            'color:rgb(255, 255, 255);'
            "background-color:hsv(%d, %d,%d);" % (r, g, b))

    # def _set_but_color(self, col):
    #     r, g, b, _ = col.getRgb()
    #     self.pushButton.setStyleSheet(
    #         'border-radius: 20px;'
    #         'color:white;'
    #         'font:bold 20px;'
    #         'padding:6px;'
    #         "background-color:hsv(%d, %d,%d);" % (r, g, b))

    status_color = pyqtProperty(QColor, fset=_set_bar_color)
    # button_color = pyqtProperty(QColor, fset=_set_but_color)


# class MyLabel(QPushButton):
#     def __init__(self, para):
#         super().__init__(para)
#
#     def _set_color(self, col):
#         # self.setAutoFillBackground(True)
#         palette = self.palette()
#         r, g, b, _ = col.getRgb()
#         # QColor.getRgb()
#         col.setHsv(r, g, b)
#         # palette.setColor(QPalette.Window, col)
#         palette.setBrush(QPalette.Button, col)
#         # palette.setColor(self.windowRole(), col)
#         self.setPalette(palette)
#
#     color = pyqtProperty(QColor, fset=_set_color)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    mainWindow.activateWindow()
    mainWindow.raise_()
    app.exec_()
    del mainWindow
    del app
